﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Patterns.DependencyInjection {

    public interface IPalette {
        ConsoleColor ForegroundColor { get; }
        ConsoleColor BackgroundColor { get; }
    }

    public interface IMessager {
        string GetMessage();
    }

    public class BlueWhitePalette : IPalette {

        public ConsoleColor ForegroundColor {
            get { return ConsoleColor.White; }
        }

        public ConsoleColor BackgroundColor {
            get { return ConsoleColor.Blue; }
        }
    }

    public class RedGreenPalette : IPalette {

        public ConsoleColor ForegroundColor {
            get { return ConsoleColor.Green; }
        }

        public ConsoleColor BackgroundColor {
            get { return ConsoleColor.Red; }
        }
    }

    public class SimpleMessager : IMessager {
        private readonly string _message;

        public SimpleMessager(string message) {
            _message = message;
        }

        public string GetMessage() {
            return _message;
        }
    }

    public class ConsoleWriter {
        private readonly IPalette _palette;
        private readonly IMessager _messager;

        public ConsoleWriter() :
            this(InversionOfControlContainer.Resolve<IPalette>(),
                 InversionOfControlContainer.Resolve<IMessager>()) { }

        public ConsoleWriter(IPalette palette, IMessager messager) {
            _palette = palette;
            _messager = messager;
        }

        public void Write() {
            Console.BackgroundColor = _palette.BackgroundColor;
            Console.ForegroundColor = _palette.ForegroundColor;
            Console.WriteLine(_messager.GetMessage());
        }
    }

    public class AppliedExample {

        public static void Run() {
            IDependencyResolver resolver = new SimpleDependencyResolver();
            resolver.Register<IPalette>(new BlueWhitePalette());
            resolver.Register<IMessager>(new SimpleMessager("Dependency Injection!"));
            
            InversionOfControlContainer.Initialize(resolver);

            ConsoleWriter writer = new ConsoleWriter();
            writer.Write();

            // Change dependencies on-the-fly
            resolver.Register<IPalette>(new RedGreenPalette());

            writer = new ConsoleWriter();
            writer.Write();
        }
    }
}
